package com.lottery.material.service.admin.system.impl;

import com.lottery.material.dao.base.BaseDao;
import com.lottery.material.entity.admin.Role;
import com.lottery.material.service.admin.system.ResourceService;
import com.lottery.material.service.admin.system.RoleService;
import com.lottery.material.service.base.impl.BaseServiceImpl;
import com.lottery.material.utils.EmptyUtil;
import com.lottery.material.common.Constats;
import com.lottery.material.dao.admin.system.RoleDao;
import com.lottery.material.entity.admin.Resource;
import com.lottery.material.utils.EqualsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Description：用户服务接口实现类
 * Created by 朱正磊 on 2019-03-22 17:41
 */
@Service
public class RoleServiceImpl extends BaseServiceImpl<Role, Integer> implements RoleService {

    private final RoleDao roleDao;

    private final ResourceService resourceService;

    @Autowired
    public RoleServiceImpl(RoleDao roleDao, @Lazy ResourceService resourceService) {
        this.roleDao = roleDao;
        this.resourceService = resourceService;
    }

    @Override
    public BaseDao<Role, Integer> getBaseDao() {
        return roleDao;
    }

    /**
     * description：添加或者修改角色
     * user 朱正磊
     * time 2019-03-23 14:42
     * @param role 角色对象
     */
    @Override
    public void saveOrUpdate(Role role) {
        if (EmptyUtil.isNotEmpty(role.getId())) { //主键不为空表示修改
            Role dbRole = findById(role.getId()); //根据主键查找唯一数据

            //设置属性值
            dbRole.setName(role.getName()); //角色名称
            dbRole.setDescription(role.getDescription()); //角色描述
            dbRole.setStatus(role.getStatus()); //角色状态
            dbRole.setUpdateTime(new Date()); //更新时间

            update(role); //更新角色
        } else { //主键为空表示新增
            role.setCreateTime(new Date()); //创建时间
            role.setUpdateTime(new Date()); //更新时间
            save(role); //保存角色
        }
    }

    /**
     * description：给角色分配资源（方法执行完毕就删除缓存）
     * user 朱正磊
     * time 2019-03-23 14:42
     * @param id 角色ID
     * @param resourceIds 资源ID数组
     */
    @Override
    @CacheEvict(value = Constats.RESOURCE_CACHE_NAME, key = "'tree_' + #id")
    public void grant(Integer id, String[] resourceIds) {
        //1、根据ID查询角色
        Role role = findById(id);

        //2、非空验证
        Assert.notNull(role, "该角色不存在！");

        //3、超级管理员角色不能进行资源分配
        Assert.isTrue(EqualsUtil.notEquals("administrator", role.getRoleKey()), "不能给超级管理员角色进行资源分配！");

        //4、给角色分配资源
        Set<Resource> resources = new HashSet<>();
        if (EmptyUtil.isNotEmpty(resourceIds)) {
            //1、传统写法
            /*for (String resourceId : resourceIds) {
                if (EmptyUtil.isEmpty(resourceId) || "0".equals(resourceId)) {
                    continue;
                }
                resources.add(resourceService.findById(Integer.valueOf(resourceId)));
            }*/

            //2、lambda写法
            //noinspection UseBulkOperation
            Arrays.stream(resourceIds)
                    .filter(e -> EmptyUtil.isNotEmpty(e) && EqualsUtil.notEquals("0", e))
                    .map(e -> resourceService.findById(Integer.valueOf(e)))
                    .collect(Collectors.toCollection(HashSet::new))
                    .forEach(resources::add);
        }
        role.setResources(resources);

        //5、更新角色
        update(role);
    }

    /**
     * description：根据查询条件获取分页
     * user 朱正磊
     * time 2019-03-23 14:42
     * @param searchText 查询条件
     * @param pageRequest 分页请求对象
     * @return 返回分页对象
     */
    @Override
    public Page<Role> findAllByLike(String searchText, PageRequest pageRequest) {
        if (EmptyUtil.isEmpty(searchText)) {
            searchText = "";
        }
        //根据角色名称或者角色描述模糊查询分页记录
        return roleDao.findAllByNameContainingOrDescriptionContaining(searchText, searchText, pageRequest);
    }

    /**
     * description：删除一条记录（重写）
     * user 朱正磊
     * time 2019-03-24 11:06
     * @param id 主键
     */
    @Override
    public void delete(Integer id) {
        Role role = findById(id); //根据主键查找唯一数据

        //超级管理员角色不能删除
        Assert.isTrue(EqualsUtil.notEquals("administrator", role.getRoleKey()), "不能删除超级管理员角色！");

        super.delete(id); //调用父类的删除方法删除该数据
    }

}
